#include "Jeu.h"
#include<stdlib.h>
#include <assert.h>
#include<stdio.h>

void jeuInit(Jeu* jeu,int n)
{
    int i,x,y;
    Ennemi e;
    assert(n>0);
    tankInit(&jeu->jeu_tank);
    nivInit(&jeu->jeu_terrain,n);
    tabdynInit(&jeu->jeu_tabennemi);
    tabdynTirInit(&jeu->jeu_tabtirennemi);
    jeu->jeu_niveau=n;
    jeu->jeu_nbennemitotale=15+n*n;
    jeu->jeu_nbennemi=4+(n*n);
    jeu->jeu_nbtirennemi=0;
    jeu->jeu_score=0;
    jeu->jeu_bonus=0;
    jeu->jeu_cle=0;
    for(i=0;i<jeu->jeu_nbennemi;i++)
    {
        do
        {
            x=rand()%jeu->jeu_terrain.dimx;
            y=rand()%jeu->jeu_terrain.dimy/4;
        }while(!terPositionValide(&jeu->jeu_terrain,x,y));
        enemInit(&e);
        e.enem_x=x;
        e.enem_y=y;
        tabdynAjouterEnnemi(&jeu->jeu_tabennemi,&e);
    }
}

void jeuLibere(Jeu* jeu)
{
    nivLibere(&jeu->jeu_terrain);
    tabdynTestament(&jeu->jeu_tabennemi);
    tabdynTirTestament(&jeu->jeu_tabtirennemi);
}

const Tir* jeuGetConstTir(const Jeu* jeu)
{
    return &jeu->jeu_tirtank;
}

int jeuGetAbscisseBonus(const Jeu* jeu)
{
    return jeu->jeu_xbonus;
}

int jeuGetOrdonneeBonus(const Jeu* jeu)
{
    return jeu->jeu_ybonus;
}

int jeuGetAbscisseCle(const Jeu* jeu)
{
    return jeu->jeu_xcle;
}

int jeuGetOrdonneeCle(const Jeu* jeu)
{
    return jeu->jeu_ycle;
}

int jeuGetScore(const Jeu* jeu)
{
    return jeu->jeu_score;
}

int jeuGetNiveau(const Jeu* jeu)
{
    return jeu->jeu_niveau;
}

int jeuGetNbEnnemi(const Jeu* jeu)
{
    return jeu->jeu_nbennemi;
}

const Tank* jeuGetTank(const Jeu* jeu)
{
    return &(jeu->jeu_tank);
}

const Terrain* jeuGetTerrain(const Jeu* jeu)
{
    return &(jeu->jeu_terrain);
}

bool jeuBonnePositonEnnemi(const Jeu *jeu,int positon,int x,int y)
{
    int i;
    bool res=true;
    if(x==jeu->jeu_tank.tank_x && y==jeu->jeu_tank.tank_y)
    {
        res=false;
    }
    else
    {
        for(i=0;i<positon;i++)
        {
            if(x==jeu->jeu_tabennemi.ad[i].enem_x && y==jeu->jeu_tabennemi.ad[i].enem_y)
            {
                res=false;
                break;
            }
        }
    }
    if(res==true)
    {
        for(i=positon+1;i<jeu->jeu_nbennemi;i++)
        {
            if(x==jeu->jeu_tabennemi.ad[i].enem_x && y==jeu->jeu_tabennemi.ad[i].enem_y)
            {
                res=false;
                break;
            }
        }
    }
    return res;
}
/**@brief jeuBonnePositionTank:->bool
<B> jeuBonnePositionTank verrifie qu'il n'y a aucun ennemi dans la future case
 qu'occupera le tank,elle permet d'eviter au tank de traverser
  les énnemis  </B> */
bool jeuBonnePositonTank(const Jeu *jeu,int x,int y)
{
    int i;
    bool res=true;
    for(i=0;i<jeu->jeu_nbennemi;i++)
    {
        if(x==jeu->jeu_tabennemi.ad[i].enem_x && y==jeu->jeu_tabennemi.ad[i].enem_y)
        {
            res=false;
            break;
        }
    }
    return res;
}

void jeuActionClavier(Jeu* jeu,const char c)
{
    switch(c)
    {
        case 'g':
            if (jeuBonnePositonTank(jeu,jeu->jeu_tank.tank_x-1,jeu->jeu_tank.tank_y))/*verifie qu'il ny a pas d'ennemi */
            {
                tankGauche(&jeu->jeu_tank,&jeu->jeu_terrain);
            }
            else
            {
                tankSetDirection(&jeu->jeu_tank,0);/*modifie la direction du tank */
            }
            break;
        case 'd': if(jeuBonnePositonTank(jeu,jeu->jeu_tank.tank_x+1,jeu->jeu_tank.tank_y))
                    {
                        tankDroit(&jeu->jeu_tank,&jeu->jeu_terrain);
                    }
                    else
                    {
                        tankSetDirection(&jeu->jeu_tank,1);/*modifie la direction du tank*/
                    }
                    break;
        case 'h': if(jeuBonnePositonTank(jeu,jeu->jeu_tank.tank_x,jeu->jeu_tank.tank_y-1))
                    {
                        tankHaut(&jeu->jeu_tank,&jeu->jeu_terrain);
                    }
                    else
                    {
                        tankSetDirection(&jeu->jeu_tank,3);
                    }
                    break;
        case 'b': if(jeuBonnePositonTank(jeu,jeu->jeu_tank.tank_x,jeu->jeu_tank.tank_y+1))
                    {
                        tankBas(&jeu->jeu_tank,&jeu->jeu_terrain);
                    }
                    else
                    {
                        tankSetDirection(&jeu->jeu_tank,2);
                    }
                    break;
        case 'x':if(jeu->jeu_tank.tank_projectile==0)/*verrifie si le tank a le droit de tirer */
                 {
                    tirInit(&jeu->jeu_tirtank,jeu->jeu_tank.tank_x,jeu->jeu_tank.tank_y,jeu->jeu_tank.tank_direction);
                    tankSetProjectile(&jeu->jeu_tank,1);
                 }
                 break;
    }
}


void jeuEvolue(Jeu* jeu)
{
    int n,i,j,var_i,i_tir,x,y,xenem,yenem,xtir,ytir,i_enem,enem_ind,tank_vie;
    Ennemi e;
    Tir tir;
    if(jeu->jeu_tank.tank_temp==1)
    {
        for(i=0;i<jeu->jeu_nbennemi;i++)
        {
            var_i=rand()%4;
            switch(var_i)
            {
                case 0:if(jeuBonnePositonEnnemi(jeu,i,jeu->jeu_tabennemi.ad[i].enem_x-1,jeu->jeu_tabennemi.ad[i].enem_y))
                        {
                            enemGauche(&jeu->jeu_tabennemi.ad[i],&jeu->jeu_terrain);
                        }
                        else
                        {
                            enemSetDirection(&jeu->jeu_tabennemi.ad[i],0);
                        }
                        break;
                case 1: if(jeuBonnePositonEnnemi(jeu,i,jeu->jeu_tabennemi.ad[i].enem_x+1,jeu->jeu_tabennemi.ad[i].enem_y))
                        {
                            enemDroit(&jeu->jeu_tabennemi.ad[i],&jeu->jeu_terrain);
                        }
                        else
                        {
                            enemSetDirection(&jeu->jeu_tabennemi.ad[i],1);
                        }
                        break;
                case 2:if(jeuBonnePositonEnnemi(jeu,i,jeu->jeu_tabennemi.ad[i].enem_x,jeu->jeu_tabennemi.ad[i].enem_y+1))
                        {
                            enemBas(&jeu->jeu_tabennemi.ad[i],&jeu->jeu_terrain);
                        }
                        else
                        {
                            enemSetDirection(&jeu->jeu_tabennemi.ad[i],2);
                        }
                        break;
                case 3:if(jeuBonnePositonEnnemi(jeu,i,jeu->jeu_tabennemi.ad[i].enem_x,jeu->jeu_tabennemi.ad[i].enem_y-1))
                        {
                            enemHaut(&jeu->jeu_tabennemi.ad[i],&jeu->jeu_terrain);
                        }
                        else
                        {
                            enemSetDirection(&jeu->jeu_tabennemi.ad[i],3);
                        }
                        break;
            }
            if(jeu->jeu_tabennemi.ad[i].enem_projectile==0)
            {
                tirInit(&tir,jeu->jeu_tabennemi.ad[i].enem_x,jeu->jeu_tabennemi.ad[i].enem_y,jeu->jeu_tabennemi.ad[i].enem_direction);
                tabdynAjouterTir(&jeu->jeu_tabtirennemi,&tir);
                n=jeu->jeu_tabtirennemi.taille_utilisee-1;
                jeu->jeu_nbtirennemi++;
                enemSetIndice(&jeu->jeu_tabennemi.ad[i],n);
                enemSetProjectile(&jeu->jeu_tabennemi.ad[i],1);
            }
        }
        for(i_tir=0;i_tir<jeu->jeu_nbtirennemi;i_tir++)
        {
            tirSetXY(&jeu->jeu_tabtirennemi.ad[i_tir]);
            x=tirGetX(&jeu->jeu_tabtirennemi.ad[i_tir]);
            y=tirGetY(&jeu->jeu_tabtirennemi.ad[i_tir]);
            if(x>0 && y>0 && y<jeu->jeu_terrain.dimy-1 && x<jeu->jeu_terrain.dimx-1)
            {
                if(terGetXY(&jeu->jeu_terrain,x,y)=='#')
                {
                    terSetXY(&jeu->jeu_terrain,x,y,' ');
                    tabdynSupprimerTir(&jeu->jeu_tabtirennemi,i_tir);
                    jeu->jeu_nbtirennemi--;
                    for(i=0;i<jeu->jeu_nbennemi;i++)
                    {
                        enem_ind=enemGetIndice(&jeu->jeu_tabennemi.ad[i]);
                        if(i_tir==enem_ind)
                        {
                            enemSetProjectile(&jeu->jeu_tabennemi.ad[i],0);
                            break;
                        }
                    }
                }
                if(terGetXY(&jeu->jeu_terrain,x,y)=='A')
                {
                    tabdynSupprimerTir(&jeu->jeu_tabtirennemi,i_tir);
                    jeu->jeu_nbtirennemi--;
                    for(i=0;i<jeu->jeu_nbennemi;i++)
                    {
                        enem_ind=enemGetIndice(&jeu->jeu_tabennemi.ad[i]);
                        if(i_tir==enem_ind)
                        {
                            enemSetProjectile(&jeu->jeu_tabennemi.ad[i],0);
                            break;
                        }
                    }
                }
                if(terGetXY(&jeu->jeu_terrain,x,y)=='B')
                {
                    tabdynSupprimerTir(&jeu->jeu_tabtirennemi,i_tir);
                    jeu->jeu_nbtirennemi--;
                    jeu->jeu_tank.tank_vie=0;
                    for(i=0;i<jeu->jeu_nbennemi;i++)
                    {
                        enem_ind=enemGetIndice(&jeu->jeu_tabennemi.ad[i]);
                        if(i_tir==enem_ind)
                        {
                            enemSetProjectile(&jeu->jeu_tabennemi.ad[i],0);
                            break;
                        }
                    }
                }
                else if(x==jeu->jeu_tank.tank_x && y==jeu->jeu_tank.tank_y)
                     {
                        tank_vie=tankGetVie(&jeu->jeu_tank);
                        tank_vie=tank_vie-1;
                        tankInit(&jeu->jeu_tank);
                        jeu->jeu_tank.tank_vie=tank_vie;
                        tabdynSupprimerTir(&jeu->jeu_tabtirennemi,i_tir);
                        jeu->jeu_nbtirennemi--;
                        for(i=0;i<jeu->jeu_nbennemi;i++)
                        {
                            enem_ind=enemGetIndice(&jeu->jeu_tabennemi.ad[i]);
                            if(i_tir==enem_ind)
                            {
                                enemSetProjectile(&jeu->jeu_tabennemi.ad[i],0);
                                break;
                            }
                        }
                     }
                     else
                     {
                        xtir=tirGetX(&jeu->jeu_tirtank);
                        ytir=tirGetY(&jeu->jeu_tirtank);
                        if(x==xtir && y==ytir)
                        {
                            tabdynSupprimerTir(&jeu->jeu_tabtirennemi,i_tir);
                            jeu->jeu_nbtirennemi--;
                            tankSetProjectile(&jeu->jeu_tank,0);
                            for(i=0;i<jeu->jeu_nbennemi;i++)
                            {
                                enem_ind=enemGetIndice(&jeu->jeu_tabennemi.ad[i]);
                                if(i_tir==enem_ind)
                                {
                                    enemSetProjectile(&jeu->jeu_tabennemi.ad[i],0);
                                    break;
                                }
                            }
                        }
                     }
            }
            else
            {
                tabdynSupprimerTir(&jeu->jeu_tabtirennemi,i_tir);
                jeu->jeu_nbtirennemi--;
                for(i=0;i<jeu->jeu_nbennemi;i++)
                {
                    enem_ind=enemGetIndice(&jeu->jeu_tabennemi.ad[i]);
                    if(i_tir==enem_ind)
                    {
                        enemSetProjectile(&jeu->jeu_tabennemi.ad[i],0);
                        break;
                    }
                }
            }
        }
    }
    if((jeu->jeu_tank.tank_projectile==1))
     {
        tirSetXY(&jeu->jeu_tirtank);
        x=tirGetX(&jeu->jeu_tirtank);
        y=tirGetY(&jeu->jeu_tirtank);
        if(x>0 && y>0 && y<jeu->jeu_terrain.dimy-1 && x<jeu->jeu_terrain.dimx-1)/* verrifie si le tir est a l'interieur du terrain */
        {
            if(terGetXY(&jeu->jeu_terrain,x,y)=='#')
            {
                terSetXY(&jeu->jeu_terrain,x,y,' ');
                tankSetProjectile(&jeu->jeu_tank,0);
            }
            if(terGetXY(&jeu->jeu_terrain,x,y)=='A')
            {
                if(jeu->jeu_tank.tank_forcetir==1)
                {
                    terSetXY(&jeu->jeu_terrain,x,y,' ');
                }
                tankSetProjectile(&jeu->jeu_tank,0);
            }
            if(terGetXY(&jeu->jeu_terrain,x,y)=='B')
            {
                jeu->jeu_tank.tank_vie=0;
            }
            else/*verifie si le tir est à la meme position d'un ennemi */
            {
                for(i_enem=0;i_enem<jeu->jeu_nbennemi;i_enem++)
                {
                    xenem=enemGetX(&jeu->jeu_tabennemi.ad[i_enem]);
                    yenem=enemGetY(&jeu->jeu_tabennemi.ad[i_enem]);
                    if(x==xenem && y==yenem)
                    {
                        tabdynSupprimerEnnemi(&jeu->jeu_tabennemi,i_enem);
                        jeu->jeu_nbennemi--;
                        tankSetProjectile(&jeu->jeu_tank,0);
                        jeu->jeu_score=jeu->jeu_score+1;
                        break;
                    }
                }
            }
            if(jeu->jeu_tank.tank_projectile==1) /*gestion des colisions entre le tir du tank et les tirs ennemis */
            {
                for(i_tir=0;i_tir<jeu->jeu_tabtirennemi.taille_utilisee;i_tir++)
                    {
                        xtir=tirGetX(&jeu->jeu_tabtirennemi.ad[i_tir]);
                        ytir=tirGetY(&jeu->jeu_tabtirennemi.ad[i_tir]);
                        if(xtir==x && ytir==y)
                        {
                            tabdynSupprimerTir(&jeu->jeu_tabtirennemi,i_tir);
                            jeu->jeu_nbtirennemi--;
                            tankSetProjectile(&jeu->jeu_tank,0);
                            for(i=0;i<jeu->jeu_nbennemi;i++)
                            {
                                enem_ind=enemGetIndice(&jeu->jeu_tabennemi.ad[i]);
                                if(i_tir==enem_ind)
                                {
                                    enemSetProjectile(&jeu->jeu_tabennemi.ad[i],0);
                                    break;
                                }
                            }
                            break;
                        }
                    }
            }
        }
        else
        {
            tankSetProjectile(&jeu->jeu_tank,0);
        }
    }
    if((jeu->jeu_nbennemi<(jeu->jeu_nbennemitotale/3)|| (jeu->jeu_nbennemi<5))&&(jeu->jeu_nbennemitotale>0))
    {
        do
        {
            xenem=rand()%jeu->jeu_terrain.dimx;
            yenem=rand()%jeu->jeu_terrain.dimy/4;
        }while(!terPositionValide(&jeu->jeu_terrain,xenem,yenem));
        enemInit(&e);
        e.enem_x=xenem;
        e.enem_y=yenem;
        tabdynAjouterEnnemi(&jeu->jeu_tabennemi,&e);
        jeu->jeu_nbennemitotale--;
        jeu->jeu_nbennemi++;
    }
    if(jeu->jeu_niveau>1 && jeu->jeu_score>5 && jeu->jeu_tank.tank_forcetir==0)
    {
        jeu->jeu_bonus=1;
    }
    if(jeu->jeu_tank.tank_x==jeu->jeu_xbonus && jeu->jeu_tank.tank_y==jeu->jeu_ybonus)
    {
        jeu->jeu_tank.tank_forcetir=1;
        jeu->jeu_bonus=0;
    }
    if(jeu->jeu_niveau>2 && jeu->jeu_tank.tank_vie<=2 && jeu->jeu_tank.tank_baseok==0)
    {
        jeu->jeu_cle=1;
    }
     if(jeu->jeu_tank.tank_x==jeu->jeu_xcle && jeu->jeu_tank.tank_y==jeu->jeu_ycle)
    {
        jeu->jeu_cle=0;
        jeu->jeu_tank.tank_baseok=1;
    }
    if(jeu->jeu_tank.tank_baseok==1)
    {
        if(jeu->jeu_niveau==3)
        {
            for(i=13;i<jeu->jeu_terrain.dimy-1;i++)
            {
                for(j=6;j<=8;j++)
                {
                    if(terGetXY(&jeu->jeu_terrain,j,i)=='#' || terGetXY(&jeu->jeu_terrain,j,i)==' ')
                    {
                        terSetXY(&jeu->jeu_terrain,j,i,'A');
                    }
                }
            }
        }
    }
    if(jeu->jeu_tank.tank_baseok==0)
    {
        if(jeu->jeu_niveau==3)
        {
            for(i=13;i<jeu->jeu_terrain.dimy-1;i++)
            {
                for(j=6;j<=8;j++)
                {
                    if(terGetXY(&jeu->jeu_terrain,j,i)=='A' || terGetXY(&jeu->jeu_terrain,j,i)==' ')
                    {
                        terSetXY(&jeu->jeu_terrain,j,i,'#');
                    }
                }
            }
        }
    }
}
